﻿using ICSharpCode.AvalonEdit.Search;
using Microsoft.Win32;
using Newtonsoft.Json;
using Org.BouncyCastle.Utilities.Encoders;
using System;
using System.IO;
using System.Text;
using System.Windows;
using System.Windows.Controls;

namespace AESUtil
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        SearchPanel searchPanel;
        public Boolean IsBase64;
        HistoryDialog historyDialog = new HistoryDialog();

        public MainWindow()
        {
            InitializeComponent();
            this.searchPanel = ICSharpCode.AvalonEdit.Search.SearchPanel.Install(this.resultBox);
            this.searchPanel.IsVisibleChanged += (sender, args) =>
            {
                if (!searchPanel.IsVisible)
                {
                    this.searchBtn.Visibility = Visibility.Visible;
                }
                else
                {
                    this.searchBtn.Visibility = Visibility.Hidden;
                }
            };
            this.setTittleText();
        }

        private String Encrypt(string input)
        {
            if(Properties.Settings.Default.algorithm == "SM4")
            {
                return SM4Util.Encrypt(input);
            }else
            {
                return AESUtils.Encrypt(input);
            }
        }
        private String Decrypt(String input)
        {
            if (Properties.Settings.Default.algorithm == "SM4")
            {
                return SM4Util.Decrypt(input);
            }
            else
            {
                return AESUtils.Decrypt(input);
            }
        }
        private void decryptBtn_Click(object sender, RoutedEventArgs e)
        {
            String oriText = this.inputBox.Text;
            try
            {
                if(IsBase64)
                {
                    this.resultBox.Text = ConvertFormatJsonString(Base64Util.getStringFromBase64String(oriText));
                    return;
                }
                String s = Decrypt(oriText);
                try
                {
                    s = ConvertFormatJsonString(s);
                }
                catch (Exception ex) {
                    System.Console.WriteLine( ex.ToString());
                }
                this.resultBox.Text = s;

            }
            catch (Exception ex)
            {
                MessageBox.Show("解密异常，请确认密文是否正确！详细信息："+ex.Message);
                this.resultBox.Text = "";
            }
        }

        private void encryptBtn_Click(object sender, RoutedEventArgs e)
        {
            String oriText = this.resultBox.Text;
            if (Properties.Settings.Default.autoFormat)
            {
                try
                {
                    oriText = ConvertOriJsonString(oriText);
                    if (IsBase64)
                    {
                        this.inputBox.Text = Convert.ToBase64String(Encoding.UTF8.GetBytes(oriText));
                        return;
                    }
                }
                catch (Exception ex)
                {
                    System.Console.WriteLine(ex.ToString());
                }
            }
            String s = Encrypt(oriText);
            this.inputBox.Text = s;
        }
        
        private void setBtn_Click(Object sender, RoutedEventArgs e)
        {
            Setting setting = new Setting();
            setting.Owner = this;
            setting.ShowDialog();
        }
        private string ConvertFormatJsonString(string str)
        {
            return JsonUtil.ConvertFormatJsonString(str);
        }
        private string ConvertOriJsonString(string str)
        {
            return JsonUtil.ConvertOriJsonString(str);
        }

        //去掉两端的引号
        private void clearQuateBtn_Click(object sender, RoutedEventArgs e)
        {
            String oriText = this.inputBox.Text;
            if (oriText.StartsWith("\""))
            {
                oriText = oriText.Substring(1);
            }
            if (oriText.EndsWith("\""))
            {
                oriText = oriText.Substring(0, oriText.Length - 1);
            }
            this.inputBox.Text = oriText;
        }

        private void searchBtn_Click(object sender, RoutedEventArgs e)
        {
            this.searchPanel.Open();
            this.searchBtn.Visibility = Visibility.Hidden;
        }

        //private void toggleButton_Checked(object sender, RoutedEventArgs e)
        //{
        //    this.IsBase64 =(bool) this.toggleButton.IsChecked;
        //    if (this.IsBase64)
        //    {
        //        this.decryptToFileBtn.Visibility = Visibility.Visible;
        //        this.encryptFileBtn.Visibility = Visibility.Visible;
        //        Grid.SetColumnSpan(this.decryptBtn, 1);
        //    }
        //    else
        //    {
        //        this.decryptToFileBtn.Visibility = Visibility.Hidden;
        //        this.encryptFileBtn.Visibility = Visibility.Hidden;
        //        Grid.SetColumnSpan(this.decryptBtn, 3);
        //    }
        //    this.setTittleText();
        //}

        private void saveToHistoryBtn_Click(object sender, RoutedEventArgs e)
        {
            SetHistoryName shn = new SetHistoryName();
            shn.Owner = this;
            bool? dialogResult =  shn.ShowDialog();
            if (dialogResult == true)
            {
                CryptItem item = new CryptItem
                {
                    Name = shn.name,
                    CryptText = this.inputBox.Text,
                    PlainText = this.resultBox.Text,
                    Mode = Properties.Settings.Default.algorithm,
                    Key = Properties.Settings.Default.KEY,
                    IV = Properties.Settings.Default.IV
                };
            
                HistoryUtil.saveToFile(item);
                if(this.historyDialog.IsLoaded)
                {
                    this.historyDialog.freshButtonClick(null, null);
                }
            }
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            historyDialog.Owner = this;
            if (Properties.Settings.Default.showHistoryDialog)
            {
                historyDialog.Show();
            }
        }

        private void showHistory_Click(object sender, RoutedEventArgs e)
        {
            this.historyDialog.Show();
        }

        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            this.historyDialog.ForceCloseButton_Click();
        }
        private void setTittleText()
        {
            if (this.IsBase64)
            {
                this.decryptToFileBtn.Visibility = Visibility.Visible;
                this.encryptFileBtn.Visibility = Visibility.Visible;
                Grid.SetColumnSpan(this.decryptBtn, 1);
            }
            else
            {
                this.decryptToFileBtn.Visibility = Visibility.Hidden;
                this.encryptFileBtn.Visibility = Visibility.Hidden;
                Grid.SetColumnSpan(this.decryptBtn, 3);
            }
            if (!this.IsBase64)
            {
                this.Title = "加解密程序  算法：" + Properties.Settings.Default.algorithm;
                this.modeBtn.Content = "算法："+ Properties.Settings.Default.algorithm;
            }
            else
            {
                this.modeBtn.Content = "算法:BASE64"; 
                this.Title = "加解密程序  算法：" + "BASE64 编解码模式";
            }

        }

        private void decryptToFileBtn_Click(object sender, RoutedEventArgs e)
        {
            String oriText = this.inputBox.Text;
            SaveFileDialog saveFileDialog = new SaveFileDialog();
            saveFileDialog.FileName = "未命名文件";
            saveFileDialog.Title = "保存文件";

            bool? result = saveFileDialog.ShowDialog();

            if (result == true) {                
                byte[] data = getByteArrayFromBase64String(oriText);
                File.WriteAllBytes(saveFileDialog.FileName, data);
            }
        }

        private void encryptFileBtn_Click(object sender, RoutedEventArgs e)
        {
           OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Multiselect = false;
            openFileDialog.Title = "打开文件";
            bool? result = openFileDialog.ShowDialog();
            if (result == true)
            {
                byte[] fileData = File.ReadAllBytes(openFileDialog.FileName);
                this.inputBox.Text = Convert.ToBase64String(fileData);
            }
        }
        private byte[] getByteArrayFromBase64String(string base64String)
        {
            return Base64Util.getByteArrayFromBase64String(base64String);
        }

        private void moreBtnClicked(object sender, RoutedEventArgs e)
        {
            MoreContextMenu.IsOpen = true;
        }

        private void sendCurlBtn_Click(object sender, RoutedEventArgs e)
        {
            SendRequest sendRequest = new SendRequest();
            sendRequest.Owner = this;
            sendRequest.Show();
        }

        private void ModeSM4Btn_Click(object sender, RoutedEventArgs e)
        {
            Properties.Settings.Default.algorithm = "SM4";
            Properties.Settings.Default.KEY = Setting.KEY_SM4;
            Properties.Settings.Default.IV = Setting.IV_SM4;
            Properties.Settings.Default.Save();
            this.IsBase64 = false;
            this.setTittleText();
        }

        private void ModeAESBtn_Click(object sender, RoutedEventArgs e)
        {
            Properties.Settings.Default.algorithm = "AES";
            Properties.Settings.Default.KEY = Setting.KEY_AES;
            Properties.Settings.Default.IV = Setting.IV_AES;
            Properties.Settings.Default.Save();
            this.IsBase64 = false;
            this.setTittleText();
        }

        private void ModeBASE64Btn_Click(object sender, RoutedEventArgs e)
        {
            this.IsBase64 = true;
            this.setTittleText();
        }

        private void modeBtnClicked(object sender, RoutedEventArgs e)
        {
            ModeContextMenu.IsOpen = true;
        }
    }
}
